from openpyxl import load_workbook
import ast

class ExcelIndexParse:
    def __init__(self, file_path):
        self.file_path = file_path
        self.sheet_info = {}

    def parse(self):
        wb = load_workbook(self.file_path)
        if len(wb.worksheets) == 0:
            print('no worksheet')
            return
        sheet = wb.worksheets[0]
        sheet_title = sheet.title
        if sheet_title.lower() != 'index':
            print('no index sheet')
            return
        for row in sheet.iter_rows(min_row=2, values_only=True):
            sheet_name = row[0]
            sheet_template = row[1]
            sheet_convert = row[2]
            sheet_export = row[3]
            self.sheet_info[sheet_name] = {
                'render': sheet_template,
                'convert': sheet_convert,
                'export': sheet_export,
            }
        wb.close()
        return self.sheet_info

class ExcelDataParser:
    def __init__(self, file_path):
        self._file_path = file_path
        self._sheet_name = ""
        self._data_list = {}
        self._srver_data = {}
        self._client_data = {}
        self._title_map = {}
        self._title_list = []

    @property
    def file_path(self):
        return self._file_path
    
    @property
    def data_list(self):
        return self._data_list
    
    @property
    def title_map(self):
        return self._title_map
    
    @property
    def title_list(self):
        return self._title_list
    
    @property
    def server_data(self):
        return self._srver_data
    
    @property
    def client_data(self):
        return self._client_data

    def parse(self, sheet_name, export):
        print(f"parsing excel file: {self.file_path}")
        wb = load_workbook(self.file_path)
        if sheet_name not in wb.sheetnames:
            print(f"sheet {sheet_name} not found in {self.file_path} {wb.sheetnames}")
            return None, None
        sheet = wb[sheet_name]
        self._sheet_name = sheet.title
        data_list = self._data_list

        # 1到4行是标题， 读取title
        for row in sheet.iter_cols(min_row=1, max_row=4,values_only=True):
            self._title_map[row[0]] = {
                'name': row[0],
                'type': row[1],
                'export': row[2] or 'cs',
                'desc': row[3],
            }
            self._title_list.append(row[0])

        title_list = self._title_list
        title_map = self._title_map
        # 从第5行开始读取数据
        for row in sheet.iter_rows(min_row=5, values_only=True):
            if not any(row):
                continue
            len_raw = len(row)
            raw_row_data = [self._parse_value(row[i], title_map[title_list[i]]['type'], i) for i in range(len_raw)]
            data_dict = dict(zip(title_list, raw_row_data))
            data_id = data_dict[title_list[0]]
            data_list[data_id] = data_dict
            
            # 对服务器数据和客户端数据进行裁剪
            srv_data = data_dict.copy()
            cli_data = data_dict.copy()
            for key, value in data_dict.items():
                field_export = title_map[key]['export'].lower()
                if field_export == 'cs':
                    continue
                if field_export == 'c':
                    srv_data.pop(key)
                elif field_export == 's':
                    cli_data.pop(key)

            if export.lower() == 'c':
                srv_data.clear()
            elif export.lower() == 's':
                cli_data.clear()

            self._srver_data[data_id] = srv_data
            self._client_data[data_id] = cli_data

        wb.close()
        return data_list, title_map
    
    def _parse_value(self, value, type_str, index):
        # print(f'{index}: value = {value}, type = {type_str}')
        if type_str == 'int':
            return int(value)
        elif type_str == 'float':
            return float(value)
        elif type_str in {'string', "text"}:
            return str(value)
        elif type_str == 'bool':
            return bool(value)
        elif type_str == 'list':
            return  ast.literal_eval(value) if value else []
        elif type_str == 'dict':
            return ast.literal_eval(value) if value else {}
        elif type_str == "note":
            return value if value else ""
        else:
            return value


if __name__ == '__main__':
    parser = ExcelIndexParse('excel/CurrencyBase3.xlsx')
    parser.parse()
